﻿/* ***********************************************
 * Author		:  kingthy
 * Email		:  kingthy@gmail.com
 * Description	:  Cache
 *
 * ***********************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Collections;
using KT.Core.Extensions;
namespace KT.Core
{
    /// <summary>
    /// System.Web.Cache缓存的封装
    /// </summary>
    public static class Cache
    {
        /// <summary>
        /// 当前应用程序的的缓存实例
        /// </summary>
        public static System.Web.Caching.Cache Current
        {
            get
            {
                return HttpRuntime.Cache;
            }
        }

        /// <summary>
        /// 已缓存的缓存项数量
        /// </summary>
        public static int Count
        {
            get
            {
                return Current.Count;
            }
        }

        /// <summary>
        /// 获取某个缓存项
        /// </summary>
        /// <param name="key">键值</param>
        /// <returns></returns>
        public static object Get(string key)
        {
            return Current.Get(key);
        }

        /// <summary>
        /// 移除某个缓存项
        /// </summary>
        /// <param name="key">键值</param>
        /// <returns></returns>
        public static object Remove(string key)
        {
            return Current.Remove(key);
        }
        /// <summary>
        /// 清除所有缓存
        /// </summary>
        public static void Clear()
        {
            var c = Current;
            foreach (DictionaryEntry v in c)
            {
                c.Remove((string)v.Key);
            }
        }
        /// <summary>
        /// 添加缓存项
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">缓存数据</param>
        public static void Add(string key, object data)
        {
            Current.Insert(key, data);
        }
        /// <summary>
        /// 添加具有一个过期时间的缓存项
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">缓存数据</param>
        /// <param name="absoluteExpiration">绝对的过期时间,到此时间后缓存过期</param>
        public static void Add(string key, object data, DateTime absoluteExpiration)
        {
            Current.Insert(key, data, null, absoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
        }
        /// <summary>
        /// 添加具有某些依赖项的缓存项
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">缓存数据</param>
        /// <param name="dependencies">依赖项</param>
        public static void Add(string key, object data, System.Web.Caching.CacheDependency dependencies)
        {
            Current.Insert(key, data, dependencies);
        }
        /// <summary>
        /// 添加与某些文件关连的缓存项,当这些文件被修改时缓存过期
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">缓存数据</param>
        /// <param name="files">缓存依赖的文件地址，当这些文件有变更时缓存项将自动失效</param>
        public static void Add(string key, object data, params string[] files)
        {
            Current.Insert(key, data, new System.Web.Caching.CacheDependency(files));
        }
        /// <summary>
        /// 添加具有一个过期时间并且与某些文件关连的缓存项,当过期时间已到或这些文件被修改时缓存过期
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">缓存数据</param>
        /// <param name="absoluteExpiration">绝对的过期时间,到此时间后缓存项自动过期</param>
        /// <param name="files">缓存依赖的文件地址，当这些文件有变更时缓存项将自动失效</param>
        public static void Add(string key, object data, DateTime absoluteExpiration, params string[] files)
        {
            Current.Insert(key, data, new System.Web.Caching.CacheDependency(files), absoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
        }
        #region GetOrAdd
        /// <summary>
        /// 返回某个缓存项,如果不存在则调用函数委托获取值,并将值存入缓存后返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存项键值</param>
        /// <param name="handler">缓存项不存在时重新获取数据的函数委托</param>
        /// <returns></returns>
        public static T GetOrAdd<T>(string key, Func<T> handler)
        {
            return (T)(Get(key).IfNull(() =>
            {
                T v = handler.Invoke();
                if (v != null)
                {
                    //存入缓存
                    Add(key, v);
                }
                return v;
            }));
        }
        /// <summary>
        /// 返回某个缓存项,如果不存在则调用函数委托获取值,并将值存入缓存后返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存项键值</param>
        /// <param name="absoluteExpiration">绝对的过期时间，当时间超过此值时缓存项将自动失效</param>
        /// <param name="handler">缓存项不存在时重新获取数据的函数委托</param>
        /// <returns></returns>
        public static T GetOrAdd<T>(string key, Func<T> handler, DateTime absoluteExpiration)
        {
            return (T)(Get(key).IfNull(() =>
            {
                T v = handler.Invoke();
                if (v != null)
                {
                    //存入缓存
                    Add(key, v, absoluteExpiration);
                }
                return v;
            }));
        }
        /// <summary>
        /// 返回某个缓存项,如果不存在则调用函数委托获取值,并将值存入缓存后返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存项键值</param>
        /// <param name="dependencies">缓存依赖</param>
        /// <param name="handler">缓存项不存在时重新获取数据的函数委托</param>
        /// <returns></returns>
        public static T GetOrAdd<T>(string key, Func<T> handler, System.Web.Caching.CacheDependency dependencies)
        {
            return (T)(Get(key).IfNull(() =>
            {
                T v = handler.Invoke();
                if (v != null)
                {
                    //存入缓存
                    Add(key, v, dependencies);
                }
                return v;
            }));
        }
        /// <summary>
        /// 返回某个缓存项,如果不存在则调用函数委托获取值,并将值存入缓存后返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存项键值</param>
        /// <param name="files">缓存依赖的文件地址，当这些文件有变更时缓存项将自动失效</param>
        /// <param name="handler">缓存项不存在时重新获取数据的函数委托</param>
        /// <returns></returns>
        public static T GetOrAdd<T>(string key, Func<T> handler, params string[] files)
        {
            return (T)(Get(key).IfNull(() =>
            {
                T v = handler.Invoke();
                if (v != null)
                {
                    //存入缓存
                    Add(key, v, files);
                }
                return v;
            }));
        }
        /// <summary>
        /// 返回某个缓存项,如果不存在则调用函数委托获取值,并将值存入缓存后返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存项键值</param>
        /// <param name="absoluteExpiration">绝对的过期时间，当时间超过此值时缓存项将自动失效</param>
        /// <param name="files">缓存依赖的文件地址，当这些文件有变更时缓存项将自动失效</param>
        /// <param name="handler">缓存项不存在时重新获取数据的函数委托</param>
        /// <returns></returns>
        public static T GetOrAdd<T>(string key, Func<T> handler, DateTime absoluteExpiration, params string[] files)
        {
            return (T)(Get(key).IfNull(() =>
            {
                T v = handler.Invoke();
                if (v != null)
                {
                    //存入缓存
                    Add(key, v, absoluteExpiration, files);
                }
                return v;
            }));
        }
        #endregion
    }
}
